# 导入SentenceTransformer库
# 这是sentence-transformers库的核心类，专门用于文本嵌入任务
from sentence_transformers import SentenceTransformer

# 初始化SentenceTransformer模型
# 有两种加载模型的方式：

# 方式1：从Hugging Face Hub在线下载（需要网络连接）
# model = SentenceTransformer("all-MiniLM-L6-v2")
# 执行这行代码时会：
# 1. 检查本地缓存是否已有该模型
# 2. 如果没有，则从Hugging Face模型仓库自动下载
# 3. 下载完成后加载到内存中

# 方式2：从本地路径加载模型（推荐，避免网络问题）
model = SentenceTransformer("D:/models/sentence-transformersall-MiniLM-L6-v2")
# 使用本地模型的优点：
# - 无需网络连接
# - 加载速度更快
# - 避免网络不稳定导致的问题
# 注意：路径中的斜杠使用正斜杠(/)或双反斜杠(\\)

# 使用模型进行文本嵌入（向量化）
# encode()方法将文本列表转换为数值向量
embeddings = model.encode([
    "This is a sample sentence.",  # 第一个文本
    "This is another sentence."    # 第二个文本
])
# encode()方法内部执行步骤：
# 1. 文本分词（Tokenization）- 将文本拆分为模型可理解的标记
# 2. 模型推理 - 通过神经网络前向传播
# 3. 池化操作 - 将标记级表示聚合成句子级表示
# 4. 归一化（如果模型配置了归一化）

# 打印嵌入结果
print(embeddings)
# 输出示例：
# [[ 0.001  -0.024   0.045  ... ]   # 第一个句子的384维嵌入向量
#  [ 0.012   0.034  -0.015  ... ]]  # 第二个句子的384维嵌入向量

# 可以进一步查看嵌入向量的详细信息：
print(f"嵌入数组类型: {type(embeddings)}")           # 通常是 <class 'numpy.ndarray'>
print(f"嵌入数组形状: {embeddings.shape}")           # 输出: (2, 384) - 2个句子，每个384维
print(f"数据类型: {embeddings.dtype}")               # 通常是 float32
print(f"第一个句子的嵌入向量前5个值: {embeddings[0][:5]}")  # 查看前5个维度值

# 高级编码选项示例（可以传入更多参数）：
# embeddings_advanced = model.encode(
#     texts,
#     batch_size=32,              # 批处理大小
#     show_progress_bar=True,     # 显示进度条
#     normalize_embeddings=True,  # 对嵌入向量进行归一化
#     convert_to_numpy=True,      # 返回numpy数组（默认）
#     convert_to_tensor=False     # 也可以返回PyTorch张量
# )

'''
三种嵌入方式详细对比：

1. SentenceTransformer（当前使用的方式）
   = 本地加载模型 + 生成向量
   特点：
     - 返回原始的numpy数组，便于科学计算
     - 可以精细控制编码参数（批处理、归一化、进度条等）
     - 支持更多原生功能和底层操作
     - 直接访问模型的所有功能
     - 性能最优，没有额外封装开销

2. HuggingFaceEmbeddings（LangChain封装）
   = 封装了 SentenceTransformer 或 HF Transformer
   特点：
     - 返回Python列表格式，易于集成
     - 接口标准化，与LangChain框架深度集成
     - 配置参数针对LangChain优化
     - 自动处理异常和边界情况
     - 适合快速开发和原型验证

3. OllamaEmbeddings（服务化部署）
   = 调用本地 Ollama 服务，模型必须先启动
   特点：
     - 通过REST API调用，解耦模型服务
     - 支持模型热更新和版本管理
     - 适合生产环境部署
     - 可以同时服务多个应用
     - 需要额外的服务维护

选择建议：
- 研究和实验：使用SentenceTransformer获得最大灵活性
- 应用开发：使用HuggingFaceEmbeddings快速集成到LangChain应用
- 生产部署：考虑OllamaEmbeddings实现服务化架构

当前模型的详细信息：
- 模型：all-MiniLM-L6-v2
- 嵌入维度：384
- 序列最大长度：256个标记
- 支持语言：多语言（包括中英文）
- 模型大小：约80MB
- 适用场景：语义搜索、聚类、文本相似度计算
'''

# 实际应用示例：
# 计算两个句子的余弦相似度
from sklearn.metrics.pairwise import cosine_similarity

# 计算两个嵌入向量之间的余弦相似度
similarity = cosine_similarity([embeddings[0]], [embeddings[1]])
# 取第一个(也是唯一一个)元素
print(f"两个句子的余弦相似度: {similarity[0][0]:.4f}")

# 批量处理大量文本的示例：
# large_texts = [f"这是第{i}个测试句子" for i in range(100)]
# large_embeddings = model.encode(large_texts, batch_size=64, show_progress_bar=True)